import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { MenuEntity } from "@entity/system/menu.entity";
import { RoleMenuEntity } from "@entity/system/roleMenu.entity";
import { ListMenuDTO, CreateMenuDTO, UpdateMenuDTO } from "@dto/system/menu.dto";
import { resBuild } from "@utils/resBuild";
import { checkKeyIsExist } from "@utils/serviceHelp";
import { listToTree } from "@utils/tree";
import { getOperator } from "@utils";

@Provide()
export class MenuService {
  @Inject()
  ctx: Context;

  @InjectEntityModel(MenuEntity)
  menuEntity: Repository<MenuEntity>;

  @InjectEntityModel(RoleMenuEntity)
  roleMenuEntity: Repository<RoleMenuEntity>;

  // 列表
  async list(queryParams: ListMenuDTO) {
    const queryBuilder = this.menuEntity.createQueryBuilder('entity');
    if(queryParams.menuName) {
      queryBuilder.andWhere(`entity.menuName like "%${queryParams.menuName}%"`)
    }
    if(queryParams.status) {
      queryBuilder.andWhere(`entity.status = ${queryParams.status}`)
    }
    queryBuilder.addOrderBy('entity.orderNum', 'ASC')
    queryBuilder.addOrderBy('entity.createTime', 'DESC')
    const rows = await queryBuilder.getMany()
    return resBuild.data(rows)
  }

  // 添加
  async create(menu: CreateMenuDTO) {
    // 新增之前先判断是否已存在
    await checkKeyIsExist(this.menuEntity,'menuName', menu.menuName)
    const myEntity = this.menuEntity.create(menu);
    myEntity.setCreateBy(getOperator(this.ctx))
    await this.menuEntity.save(myEntity);
    return resBuild.success()
  }

  // 删除
  async delete(menuId: string) {
    const ids = menuId.split(',').map(id => Number(id));
    await this.menuEntity.delete(ids);
    return resBuild.success()
  }

  // 修改
  async update(menu: UpdateMenuDTO) {
    const myEntity = this.menuEntity.create(menu);
    myEntity.setUpdateBy(getOperator(this.ctx))
    await this.menuEntity.save(menu);
    return resBuild.success()
  }

  // 详情
  async detail(menuId: number) {
    const detailInfo = await this.menuEntity.findOneBy({
      menuId,
    });
    return resBuild.data(detailInfo)
  }

  // 树状结构
  async treeSelect() {
    const rows = await this.menuEntity.find({
      select: ['menuId', 'menuName', 'parentId'],
      order: {
        orderNum: 'ASC',
        createTime: 'DESC'
      }
    })
    const arr2 = listToTree(rows, 'menuId', 'menuName')
    return resBuild.data(arr2)
  }

  // 角色弹框使用，根据角色id获取菜单树状结构
  async getTreeSelectByRoleId(roleId: number) {
    // 获取处理过的菜单树状结构，就是上面的
    const { data } = await this.treeSelect();
    const selectedMenuIds = await this.roleMenuEntity.find({
      select: ['menuId'],
      where: {
        roleId
      }
    })
    return resBuild.more({
      menus: data,
      checkedKeys: selectedMenuIds.map(item => item.menuId)
    })
  }
}
